package com.aluka.nirvana.framework.datasource.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.aluka.nirvana.framework.datasource.model.DataSourceWrap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.env.Environment;

import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

/**
 * @author gongli
 * @since 2019/12/16
 */
public class EnvironmentPaser {

    public static <T> T parser(Environment env, String propertyName ,Class<T> tClass){
        Binder binder = Binder.get(env);
        return binder.bind(propertyName, tClass).get();
    }

    /**
     * 根据属性名获取具体属性Map，Map k : 属性名 v : 指定类型
     * @param env Spring 环境变量
     * @param propertyName 属性名称
     * @param tClass Map value类型
     * @return Map
     */
    public static <T> Map<String,T> parserMap(Environment env, String propertyName , Class<T> tClass){
        Map<String,T> map = Maps.newHashMap();
        Binder binder = Binder.get(env);
        Properties properties = binder.bind(propertyName, Properties.class).get();
        properties.keySet().forEach(e -> {
            String p = e.toString();
            if(p.contains(".") && !map.containsKey(p.substring(0,p.indexOf(".")))){
                map.put(p.substring(0,p.indexOf(".")),binder.bind(propertyName + "." + p.substring(0,p.indexOf(".")), tClass).get());
            }
        });
        return map;
    }


    public static void druidPropSetting(DruidDataSource dataSource, DataSourceWrap dataSourceWrap) {
        dataSource.setName(dataSourceWrap.getName());
        dataSource.setUrl(dataSourceWrap.getUrl());
        dataSource.setUsername(dataSourceWrap.getUsername());
        dataSource.setPassword(dataSourceWrap.getPassword());
        if (null != dataSourceWrap.getDriverClassName()) {
            dataSource.setDriverClassName(dataSourceWrap.getDriverClassName());
        }
        if (null != dataSourceWrap.getInitialSize()) {
            dataSource.setInitialSize(dataSourceWrap.getInitialSize());
        }
        if (null != dataSourceWrap.getMaxActive()) {
            dataSource.setMaxActive(dataSourceWrap.getMaxActive());
        }

        if (null != dataSourceWrap.getMinIdle()) {
            dataSource.setMinIdle(dataSourceWrap.getMinIdle());
        }

        if (null != dataSourceWrap.getMaxWait()) {
            dataSource.setMaxWait(dataSourceWrap.getMaxWait());
        }

        if (null != dataSourceWrap.getPoolPreparedStatements()) {
            dataSource.setPoolPreparedStatements(dataSourceWrap.getPoolPreparedStatements());
        }

        if (null != dataSourceWrap.getMaxOpenPreparedStatements()) {
            dataSource.setMaxOpenPreparedStatements(dataSourceWrap.getMaxOpenPreparedStatements());
        }

        if (null != dataSourceWrap.getValidationQuery()) {
            dataSource.setValidationQuery(dataSourceWrap.getValidationQuery());
        }

        if (null != dataSourceWrap.getTestOnBorrow()) {
            dataSource.setTestOnBorrow(dataSourceWrap.getTestOnBorrow());
        }

        if (null != dataSourceWrap.getTestOnReturn()) {
            dataSource.setTestOnReturn(dataSourceWrap.getTestOnReturn());
        }

        if (null != dataSourceWrap.getTestWhileIdle()) {
            dataSource.setTestWhileIdle(dataSourceWrap.getTestWhileIdle());
        }

        if (null != dataSourceWrap.getTimeBetweenEvictionRunsMillis()) {
            dataSource.setTimeBetweenEvictionRunsMillis(dataSourceWrap.getTimeBetweenEvictionRunsMillis());
        }

        if (null != dataSourceWrap.getMinEvictableIdleTimeMillis()) {
            dataSource.setMinEvictableIdleTimeMillis(dataSourceWrap.getMinEvictableIdleTimeMillis());
        }

        if (null != dataSourceWrap.getConnectionInitSqls()) {
            dataSource.setConnectionInitSqls(Lists.newArrayList(dataSourceWrap.getConnectionInitSqls()));
        }

        if (null != dataSourceWrap.getFilters()) {
            try {
                dataSource.setFilters(dataSourceWrap.getFilters());
            } catch (SQLException ignore) {

            }
        }

        if (null != dataSourceWrap.getRemoveAbandoned()) {
            dataSource.setRemoveAbandoned(dataSourceWrap.getRemoveAbandoned());
        }

        if (null != dataSourceWrap.getRemoveAbandonedTimeout()) {
            dataSource.setRemoveAbandonedTimeout(dataSourceWrap.getRemoveAbandonedTimeout());
        }

        if (null != dataSourceWrap.getLogAbandoned()) {
            dataSource.setLogAbandoned(dataSourceWrap.getLogAbandoned());
        }

    }

    public static void propertyValuesSetting(MutablePropertyValues mpv, DataSourceWrap dataSourceWrap) {
        mpv.addPropertyValue("name", dataSourceWrap.getName());
        mpv.addPropertyValue("url", dataSourceWrap.getUrl());
        mpv.addPropertyValue("username", dataSourceWrap.getUsername());
        mpv.addPropertyValue("password", dataSourceWrap.getPassword());
        if (null != dataSourceWrap.getDriverClassName()) {
            mpv.addPropertyValue("driverClassName", dataSourceWrap.getDriverClassName());
        }
        if (null != dataSourceWrap.getInitialSize()) {
            mpv.addPropertyValue("initialSize", dataSourceWrap.getInitialSize());
        }
        if (null != dataSourceWrap.getMaxActive()) {
            mpv.addPropertyValue("maxActive", dataSourceWrap.getMaxActive());
        }

        if (null != dataSourceWrap.getMinIdle()) {
            mpv.addPropertyValue("minIdle", dataSourceWrap.getMinIdle());
        }

        if (null != dataSourceWrap.getMaxWait()) {
            mpv.addPropertyValue("maxWait", dataSourceWrap.getMaxWait());
        }

        if (null != dataSourceWrap.getPoolPreparedStatements()) {
            mpv.addPropertyValue("poolPreparedStatements", dataSourceWrap.getPoolPreparedStatements());
        }

        if (null != dataSourceWrap.getMaxOpenPreparedStatements()) {
            mpv.addPropertyValue("maxOpenPreparedStatements", dataSourceWrap.getMaxOpenPreparedStatements());
        }

        if (null != dataSourceWrap.getValidationQuery()) {
            mpv.addPropertyValue("validationQuery", dataSourceWrap.getValidationQuery());
        }

        if (null != dataSourceWrap.getTestOnBorrow()) {
            mpv.addPropertyValue("testOnBorrow", dataSourceWrap.getTestOnBorrow());
        }

        if (null != dataSourceWrap.getTestOnReturn()) {
            mpv.addPropertyValue("testOnReturn", dataSourceWrap.getTestOnReturn());
        }

        if (null != dataSourceWrap.getTestWhileIdle()) {
            mpv.addPropertyValue("testWhileIdle", dataSourceWrap.getTestWhileIdle());
        }

        if (null != dataSourceWrap.getTimeBetweenEvictionRunsMillis()) {
            mpv.addPropertyValue("timeBetweenEvictionRunsMillis", dataSourceWrap.getTimeBetweenEvictionRunsMillis());
        }

        if (null != dataSourceWrap.getMinEvictableIdleTimeMillis()) {
            mpv.addPropertyValue("minEvictableIdleTimeMillis", dataSourceWrap.getMinEvictableIdleTimeMillis());
        }

        if (null != dataSourceWrap.getConnectionInitSqls()) {
            mpv.addPropertyValue("connectionInitSqls", dataSourceWrap.getConnectionInitSqls());
        }

        if (null != dataSourceWrap.getConnectionProperties()) {
            mpv.addPropertyValue("connectionProperties", dataSourceWrap.getConnectionProperties());
        }

        if (null != dataSourceWrap.getFilters()) {
            mpv.addPropertyValue("filters", dataSourceWrap.getFilters());
        }

        if (null != dataSourceWrap.getProxyFilters()) {
            mpv.addPropertyValue("proxyFilters", dataSourceWrap.getProxyFilters());
        }

        if (null != dataSourceWrap.getRemoveAbandoned()) {
            mpv.addPropertyValue("removeAbandoned", dataSourceWrap.getRemoveAbandoned());
        }

        if (null != dataSourceWrap.getRemoveAbandonedTimeout()) {
            mpv.addPropertyValue("removeAbandonedTimeout", dataSourceWrap.getRemoveAbandonedTimeout());
        }

        if (null != dataSourceWrap.getLogAbandoned()) {
            mpv.addPropertyValue("logAbandoned", dataSourceWrap.getLogAbandoned());
        }

    }
}
